package com.chinaisafe.gateway.core.auth;

import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.chinaisafe.base.common.dto.auth.AuthUser;
import com.chinaisafe.base.common.dto.auth.Tenancy;
import com.chinaisafe.base.common.enums.AnswerCodeEnum;
import com.chinaisafe.base.common.vo.Answer;
import com.chinaisafe.gateway.sdk.constant.GateWayConstant;
import com.chinaisafe.gateway.sdk.enums.ApiTypeEnum;
import com.chinaisafe.gateway.server.service.auth.AbstractUserAuthenticationHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.Map;
import java.util.Objects;

/**
 * AuthenticationHandle
 *
 * @author xuefu.shu
 * @date 2024-07-03 10:42
 */
@Slf4j
@Component
public class AuthorizedApiUserAuthenticationHandleImpl extends AbstractUserAuthenticationHandle {

    @Autowired
    private SaTokenDao saTokenDao;

    @Override
    public Answer<AuthUser> apply(ServerWebExchange exchange, GatewayFilterChain chain, Map<String, String> headers) {
        log.info("Authorized auth");

        String tokenValue = StpUtil.getTokenValue();
        Object userId = StpUtil.getLoginIdByToken(tokenValue);

        if (Objects.isNull(userId)) {
            return Answer.create(AnswerCodeEnum.NO_AUTH, AnswerCodeEnum.NO_AUTH.getMessage(), null);
        }

        AuthUser authUser = null;
        String tenancyStr = saTokenDao.get(StrUtil.format(GateWayConstant.TENANCY_REDIS_KEY, tokenValue));
        if (StrUtil.isNotBlank(tenancyStr)) {
            authUser = JSONUtil.toBean(tenancyStr, AuthUser.class);
        }
        if (Objects.nonNull(authUser)) {
            return Answer.successWithData(authUser);
        }

        return Answer.create(AnswerCodeEnum.NO_AUTH, AnswerCodeEnum.NO_AUTH.getMessage(), null);
    }

    @Override
    public ApiTypeEnum getApiType() {
        return ApiTypeEnum.AUTHORIZED_API;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
